﻿using System;
using Mono.Cecil.PE;
using Mono.Collections.Generic;

namespace Mono.Cecil.Cil
{
	// Token: 0x02000114 RID: 276
	internal sealed class CodeReader : BinaryStreamReader
	{
		// Token: 0x170002C3 RID: 707
		// (get) Token: 0x06000A62 RID: 2658 RVA: 0x0002EA94 File Offset: 0x0002CC94
		private int Offset
		{
			get
			{
				return base.Position - this.start;
			}
		}

		// Token: 0x06000A63 RID: 2659 RVA: 0x00005BEA File Offset: 0x00003DEA
		public CodeReader(MetadataReader reader) : base(reader.image.Stream.value)
		{
			this.reader = reader;
		}

		// Token: 0x06000A64 RID: 2660 RVA: 0x0002EAB4 File Offset: 0x0002CCB4
		public int MoveTo(MethodDefinition method)
		{
			this.method = method;
			this.reader.context = method;
			int position = base.Position;
			base.Position = (int)this.reader.image.ResolveVirtualAddress((uint)method.RVA);
			return position;
		}

		// Token: 0x06000A65 RID: 2661 RVA: 0x00005C0B File Offset: 0x00003E0B
		public void MoveBackTo(int position)
		{
			this.reader.context = null;
			base.Position = position;
		}

		// Token: 0x06000A66 RID: 2662 RVA: 0x0002EB00 File Offset: 0x0002CD00
		public MethodBody ReadMethodBody(MethodDefinition method)
		{
			int position = this.MoveTo(method);
			this.body = new MethodBody(method);
			this.ReadMethodBody();
			this.MoveBackTo(position);
			return this.body;
		}

		// Token: 0x06000A67 RID: 2663 RVA: 0x0002EB3C File Offset: 0x0002CD3C
		public int ReadCodeSize(MethodDefinition method)
		{
			int position = this.MoveTo(method);
			int result = this.ReadCodeSize();
			this.MoveBackTo(position);
			return result;
		}

		// Token: 0x06000A68 RID: 2664 RVA: 0x0002EB68 File Offset: 0x0002CD68
		private int ReadCodeSize()
		{
			byte b = this.ReadByte();
			int num = (int)(b & 3);
			int num2 = num;
			int result;
			if (num2 != 2)
			{
				if (num2 != 3)
				{
					throw new InvalidOperationException();
				}
				base.Advance(3);
				result = (int)this.ReadUInt32();
			}
			else
			{
				result = b >> 2;
			}
			return result;
		}

		// Token: 0x06000A69 RID: 2665 RVA: 0x0002EBB0 File Offset: 0x0002CDB0
		private void ReadMethodBody()
		{
			byte b = this.ReadByte();
			int num = (int)(b & 3);
			int num2 = num;
			if (num2 != 2)
			{
				if (num2 != 3)
				{
					throw new InvalidOperationException();
				}
				base.Advance(-1);
				this.ReadFatMethod();
			}
			else
			{
				this.body.code_size = b >> 2;
				this.body.MaxStackSize = 8;
				this.ReadCode();
			}
			ISymbolReader symbol_reader = this.reader.module.symbol_reader;
			bool flag = symbol_reader != null && this.method.debug_info == null;
			if (flag)
			{
				this.method.debug_info = symbol_reader.Read(this.method);
			}
			bool flag2 = this.method.debug_info != null;
			if (flag2)
			{
				this.ReadDebugInfo();
			}
		}

		// Token: 0x06000A6A RID: 2666 RVA: 0x0002EC70 File Offset: 0x0002CE70
		private void ReadFatMethod()
		{
			ushort num = this.ReadUInt16();
			this.body.max_stack_size = (int)this.ReadUInt16();
			this.body.code_size = (int)this.ReadUInt32();
			this.body.local_var_token = new MetadataToken(this.ReadUInt32());
			this.body.init_locals = ((num & 16) > 0);
			bool flag = this.body.local_var_token.RID > 0U;
			if (flag)
			{
				this.body.variables = this.ReadVariables(this.body.local_var_token);
			}
			this.ReadCode();
			bool flag2 = (num & 8) > 0;
			if (flag2)
			{
				this.ReadSection();
			}
		}

		// Token: 0x06000A6B RID: 2667 RVA: 0x0002ED1C File Offset: 0x0002CF1C
		public VariableDefinitionCollection ReadVariables(MetadataToken local_var_token)
		{
			int position = this.reader.position;
			VariableDefinitionCollection result = this.reader.ReadVariables(local_var_token, this.method);
			this.reader.position = position;
			return result;
		}

		// Token: 0x06000A6C RID: 2668 RVA: 0x0002ED5C File Offset: 0x0002CF5C
		private void ReadCode()
		{
			this.start = base.Position;
			int num = this.body.code_size;
			bool flag = num < 0 || (long)base.Length <= (long)((ulong)(num + base.Position));
			if (flag)
			{
				num = 0;
			}
			int num2 = this.start + num;
			Collection<Instruction> collection = this.body.instructions = new InstructionCollection(this.method, (num + 1) / 2);
			while (base.Position < num2)
			{
				int offset = base.Position - this.start;
				OpCode opCode = this.ReadOpCode();
				Instruction instruction = new Instruction(offset, opCode);
				bool flag2 = opCode.OperandType != OperandType.InlineNone;
				if (flag2)
				{
					instruction.operand = this.ReadOperand(instruction);
				}
				collection.Add(instruction);
			}
			this.ResolveBranches(collection);
		}

		// Token: 0x06000A6D RID: 2669 RVA: 0x0002EE38 File Offset: 0x0002D038
		private OpCode ReadOpCode()
		{
			byte b = this.ReadByte();
			return (b != 254) ? OpCodes.OneByteOpCode[(int)b] : OpCodes.TwoBytesOpCode[(int)this.ReadByte()];
		}

		// Token: 0x06000A6E RID: 2670 RVA: 0x0002EE78 File Offset: 0x0002D078
		private object ReadOperand(Instruction instruction)
		{
			switch (instruction.opcode.OperandType)
			{
			case OperandType.InlineBrTarget:
				return this.ReadInt32() + this.Offset;
			case OperandType.InlineField:
			case OperandType.InlineMethod:
			case OperandType.InlineTok:
			case OperandType.InlineType:
				return this.reader.LookupToken(this.ReadToken());
			case OperandType.InlineI:
				return this.ReadInt32();
			case OperandType.InlineI8:
				return this.ReadInt64();
			case OperandType.InlineR:
				return this.ReadDouble();
			case OperandType.InlineSig:
				return this.GetCallSite(this.ReadToken());
			case OperandType.InlineString:
				return this.GetString(this.ReadToken());
			case OperandType.InlineSwitch:
			{
				int num = this.ReadInt32();
				int num2 = this.Offset + 4 * num;
				int[] array = new int[num];
				for (int i = 0; i < num; i++)
				{
					array[i] = num2 + this.ReadInt32();
				}
				return array;
			}
			case OperandType.InlineVar:
				return this.GetVariable((int)this.ReadUInt16());
			case OperandType.InlineArg:
				return this.GetParameter((int)this.ReadUInt16());
			case OperandType.ShortInlineBrTarget:
				return (int)this.ReadSByte() + this.Offset;
			case OperandType.ShortInlineI:
			{
				bool flag = instruction.opcode == OpCodes.Ldc_I4_S;
				if (flag)
				{
					return this.ReadSByte();
				}
				return this.ReadByte();
			}
			case OperandType.ShortInlineR:
				return this.ReadSingle();
			case OperandType.ShortInlineVar:
				return this.GetVariable((int)this.ReadByte());
			case OperandType.ShortInlineArg:
				return this.GetParameter((int)this.ReadByte());
			}
			throw new NotSupportedException();
		}

		// Token: 0x06000A6F RID: 2671 RVA: 0x0002F064 File Offset: 0x0002D264
		public string GetString(MetadataToken token)
		{
			return this.reader.image.UserStringHeap.Read(token.RID);
		}

		// Token: 0x06000A70 RID: 2672 RVA: 0x0002F094 File Offset: 0x0002D294
		public ParameterDefinition GetParameter(int index)
		{
			return this.body.GetParameter(index);
		}

		// Token: 0x06000A71 RID: 2673 RVA: 0x0002F0B4 File Offset: 0x0002D2B4
		public VariableDefinition GetVariable(int index)
		{
			return this.body.GetVariable(index);
		}

		// Token: 0x06000A72 RID: 2674 RVA: 0x0002F0D4 File Offset: 0x0002D2D4
		public CallSite GetCallSite(MetadataToken token)
		{
			return this.reader.ReadCallSite(token);
		}

		// Token: 0x06000A73 RID: 2675 RVA: 0x0002F0F4 File Offset: 0x0002D2F4
		private void ResolveBranches(Collection<Instruction> instructions)
		{
			Instruction[] items = instructions.items;
			int size = instructions.size;
			int i = 0;
			while (i < size)
			{
				Instruction instruction = items[i];
				OperandType operandType = instruction.opcode.OperandType;
				OperandType operandType2 = operandType;
				if (operandType2 == OperandType.InlineBrTarget)
				{
					goto IL_42;
				}
				if (operandType2 != OperandType.InlineSwitch)
				{
					if (operandType2 == OperandType.ShortInlineBrTarget)
					{
						goto IL_42;
					}
				}
				else
				{
					int[] array = (int[])instruction.operand;
					Instruction[] array2 = new Instruction[array.Length];
					for (int j = 0; j < array.Length; j++)
					{
						array2[j] = this.GetInstruction(array[j]);
					}
					instruction.operand = array2;
				}
				IL_A6:
				i++;
				continue;
				IL_42:
				instruction.operand = this.GetInstruction((int)instruction.operand);
				goto IL_A6;
			}
		}

		// Token: 0x06000A74 RID: 2676 RVA: 0x0002F1BC File Offset: 0x0002D3BC
		private Instruction GetInstruction(int offset)
		{
			return CodeReader.GetInstruction(this.body.Instructions, offset);
		}

		// Token: 0x06000A75 RID: 2677 RVA: 0x0002F1E0 File Offset: 0x0002D3E0
		private static Instruction GetInstruction(Collection<Instruction> instructions, int offset)
		{
			int size = instructions.size;
			Instruction[] items = instructions.items;
			bool flag = offset < 0 || offset > items[size - 1].offset;
			Instruction result;
			if (flag)
			{
				result = null;
			}
			else
			{
				int i = 0;
				int num = size - 1;
				while (i <= num)
				{
					int num2 = i + (num - i) / 2;
					Instruction instruction = items[num2];
					int offset2 = instruction.offset;
					bool flag2 = offset == offset2;
					if (flag2)
					{
						return instruction;
					}
					bool flag3 = offset < offset2;
					if (flag3)
					{
						num = num2 - 1;
					}
					else
					{
						i = num2 + 1;
					}
				}
				result = null;
			}
			return result;
		}

		// Token: 0x06000A76 RID: 2678 RVA: 0x0002F27C File Offset: 0x0002D47C
		private void ReadSection()
		{
			base.Align(4);
			byte b = this.ReadByte();
			bool flag = (b & 64) == 0;
			if (flag)
			{
				this.ReadSmallSection();
			}
			else
			{
				this.ReadFatSection();
			}
			bool flag2 = (b & 128) > 0;
			if (flag2)
			{
				this.ReadSection();
			}
		}

		// Token: 0x06000A77 RID: 2679 RVA: 0x0002F2CC File Offset: 0x0002D4CC
		private void ReadSmallSection()
		{
			int count = (int)(this.ReadByte() / 12);
			base.Advance(2);
			this.ReadExceptionHandlers(count, () => (int)this.ReadUInt16(), () => (int)this.ReadByte());
		}

		// Token: 0x06000A78 RID: 2680 RVA: 0x0002F30C File Offset: 0x0002D50C
		private void ReadFatSection()
		{
			base.Advance(-1);
			int count = (this.ReadInt32() >> 8) / 24;
			this.ReadExceptionHandlers(count, new Func<int>(this.ReadInt32), new Func<int>(this.ReadInt32));
		}

		// Token: 0x06000A79 RID: 2681 RVA: 0x0002F350 File Offset: 0x0002D550
		private void ReadExceptionHandlers(int count, Func<int> read_entry, Func<int> read_length)
		{
			for (int i = 0; i < count; i++)
			{
				ExceptionHandler exceptionHandler = new ExceptionHandler((ExceptionHandlerType)(read_entry() & 7));
				exceptionHandler.TryStart = this.GetInstruction(read_entry());
				exceptionHandler.TryEnd = this.GetInstruction(exceptionHandler.TryStart.Offset + read_length());
				exceptionHandler.HandlerStart = this.GetInstruction(read_entry());
				exceptionHandler.HandlerEnd = this.GetInstruction(exceptionHandler.HandlerStart.Offset + read_length());
				this.ReadExceptionHandlerSpecific(exceptionHandler);
				this.body.ExceptionHandlers.Add(exceptionHandler);
			}
		}

		// Token: 0x06000A7A RID: 2682 RVA: 0x0002F404 File Offset: 0x0002D604
		private void ReadExceptionHandlerSpecific(ExceptionHandler handler)
		{
			ExceptionHandlerType handlerType = handler.HandlerType;
			ExceptionHandlerType exceptionHandlerType = handlerType;
			if (exceptionHandlerType != ExceptionHandlerType.Catch)
			{
				if (exceptionHandlerType != ExceptionHandlerType.Filter)
				{
					base.Advance(4);
				}
				else
				{
					handler.FilterStart = this.GetInstruction(this.ReadInt32());
				}
			}
			else
			{
				handler.CatchType = (TypeReference)this.reader.LookupToken(this.ReadToken());
			}
		}

		// Token: 0x06000A7B RID: 2683 RVA: 0x0002F464 File Offset: 0x0002D664
		public MetadataToken ReadToken()
		{
			return new MetadataToken(this.ReadUInt32());
		}

		// Token: 0x06000A7C RID: 2684 RVA: 0x0002F484 File Offset: 0x0002D684
		private void ReadDebugInfo()
		{
			bool flag = this.method.debug_info.sequence_points != null;
			if (flag)
			{
				this.ReadSequencePoints();
			}
			bool flag2 = this.method.debug_info.scope != null;
			if (flag2)
			{
				this.ReadScope(this.method.debug_info.scope);
			}
			bool flag3 = this.method.custom_infos != null;
			if (flag3)
			{
				this.ReadCustomDebugInformations(this.method);
			}
		}

		// Token: 0x06000A7D RID: 2685 RVA: 0x0002F500 File Offset: 0x0002D700
		private void ReadCustomDebugInformations(MethodDefinition method)
		{
			Collection<CustomDebugInformation> custom_infos = method.custom_infos;
			for (int i = 0; i < custom_infos.Count; i++)
			{
				StateMachineScopeDebugInformation stateMachineScopeDebugInformation = custom_infos[i] as StateMachineScopeDebugInformation;
				bool flag = stateMachineScopeDebugInformation != null;
				if (flag)
				{
					this.ReadStateMachineScope(stateMachineScopeDebugInformation);
				}
				AsyncMethodBodyDebugInformation asyncMethodBodyDebugInformation = custom_infos[i] as AsyncMethodBodyDebugInformation;
				bool flag2 = asyncMethodBodyDebugInformation != null;
				if (flag2)
				{
					this.ReadAsyncMethodBody(asyncMethodBodyDebugInformation);
				}
			}
		}

		// Token: 0x06000A7E RID: 2686 RVA: 0x0002F56C File Offset: 0x0002D76C
		private void ReadAsyncMethodBody(AsyncMethodBodyDebugInformation async_method)
		{
			bool flag = async_method.catch_handler.Offset > -1;
			if (flag)
			{
				async_method.catch_handler = new InstructionOffset(this.GetInstruction(async_method.catch_handler.Offset));
			}
			bool flag2 = !async_method.yields.IsNullOrEmpty<InstructionOffset>();
			if (flag2)
			{
				for (int i = 0; i < async_method.yields.Count; i++)
				{
					async_method.yields[i] = new InstructionOffset(this.GetInstruction(async_method.yields[i].Offset));
				}
			}
			bool flag3 = !async_method.resumes.IsNullOrEmpty<InstructionOffset>();
			if (flag3)
			{
				for (int j = 0; j < async_method.resumes.Count; j++)
				{
					async_method.resumes[j] = new InstructionOffset(this.GetInstruction(async_method.resumes[j].Offset));
				}
			}
		}

		// Token: 0x06000A7F RID: 2687 RVA: 0x0002F664 File Offset: 0x0002D864
		private void ReadStateMachineScope(StateMachineScopeDebugInformation state_machine_scope)
		{
			bool flag = state_machine_scope.scopes.IsNullOrEmpty<StateMachineScope>();
			if (!flag)
			{
				foreach (StateMachineScope stateMachineScope in state_machine_scope.scopes)
				{
					stateMachineScope.start = new InstructionOffset(this.GetInstruction(stateMachineScope.start.Offset));
					Instruction instruction = this.GetInstruction(stateMachineScope.end.Offset);
					stateMachineScope.end = ((instruction == null) ? default(InstructionOffset) : new InstructionOffset(instruction));
				}
			}
		}

		// Token: 0x06000A80 RID: 2688 RVA: 0x0002F710 File Offset: 0x0002D910
		private void ReadSequencePoints()
		{
			MethodDebugInformation debug_info = this.method.debug_info;
			for (int i = 0; i < debug_info.sequence_points.Count; i++)
			{
				SequencePoint sequencePoint = debug_info.sequence_points[i];
				Instruction instruction = this.GetInstruction(sequencePoint.Offset);
				bool flag = instruction != null;
				if (flag)
				{
					sequencePoint.offset = new InstructionOffset(instruction);
				}
			}
		}

		// Token: 0x06000A81 RID: 2689 RVA: 0x0002F778 File Offset: 0x0002D978
		private void ReadScopes(Collection<ScopeDebugInformation> scopes)
		{
			for (int i = 0; i < scopes.Count; i++)
			{
				this.ReadScope(scopes[i]);
			}
		}

		// Token: 0x06000A82 RID: 2690 RVA: 0x0002F7AC File Offset: 0x0002D9AC
		private void ReadScope(ScopeDebugInformation scope)
		{
			Instruction instruction = this.GetInstruction(scope.Start.Offset);
			bool flag = instruction != null;
			if (flag)
			{
				scope.Start = new InstructionOffset(instruction);
			}
			Instruction instruction2 = this.GetInstruction(scope.End.Offset);
			scope.End = ((instruction2 != null) ? new InstructionOffset(instruction2) : default(InstructionOffset));
			bool flag2 = !scope.variables.IsNullOrEmpty<VariableDebugInformation>();
			if (flag2)
			{
				for (int i = 0; i < scope.variables.Count; i++)
				{
					VariableDebugInformation variableDebugInformation = scope.variables[i];
					VariableDefinition variable = this.GetVariable(variableDebugInformation.Index);
					bool flag3 = variable != null;
					if (flag3)
					{
						variableDebugInformation.index = new VariableIndex(variable);
					}
				}
			}
			bool flag4 = !scope.scopes.IsNullOrEmpty<ScopeDebugInformation>();
			if (flag4)
			{
				this.ReadScopes(scope.scopes);
			}
		}

		// Token: 0x06000A83 RID: 2691 RVA: 0x0002F8A4 File Offset: 0x0002DAA4
		public ByteBuffer PatchRawMethodBody(MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token)
		{
			int position = this.MoveTo(method);
			ByteBuffer byteBuffer = new ByteBuffer();
			byte b = this.ReadByte();
			int num = (int)(b & 3);
			int num2 = num;
			if (num2 != 2)
			{
				if (num2 != 3)
				{
					throw new NotSupportedException();
				}
				base.Advance(-1);
				this.PatchRawFatMethod(byteBuffer, writer, out code_size, out local_var_token);
			}
			else
			{
				byteBuffer.WriteByte(b);
				local_var_token = MetadataToken.Zero;
				code_size = b >> 2;
				this.PatchRawCode(byteBuffer, code_size, writer);
			}
			this.MoveBackTo(position);
			return byteBuffer;
		}

		// Token: 0x06000A84 RID: 2692 RVA: 0x0002F92C File Offset: 0x0002DB2C
		private void PatchRawFatMethod(ByteBuffer buffer, CodeWriter writer, out int code_size, out MetadataToken local_var_token)
		{
			ushort num = this.ReadUInt16();
			buffer.WriteUInt16(num);
			buffer.WriteUInt16(this.ReadUInt16());
			code_size = this.ReadInt32();
			buffer.WriteInt32(code_size);
			local_var_token = this.ReadToken();
			bool flag = local_var_token.RID > 0U;
			if (flag)
			{
				VariableDefinitionCollection variableDefinitionCollection = this.ReadVariables(local_var_token);
				buffer.WriteUInt32((variableDefinitionCollection != null) ? writer.GetStandAloneSignature(variableDefinitionCollection).ToUInt32() : 0U);
			}
			else
			{
				buffer.WriteUInt32(0U);
			}
			this.PatchRawCode(buffer, code_size, writer);
			bool flag2 = (num & 8) > 0;
			if (flag2)
			{
				this.PatchRawSection(buffer, writer.metadata);
			}
		}

		// Token: 0x06000A85 RID: 2693 RVA: 0x0002F9E0 File Offset: 0x0002DBE0
		private void PatchRawCode(ByteBuffer buffer, int code_size, CodeWriter writer)
		{
			MetadataBuilder metadata = writer.metadata;
			buffer.WriteBytes(this.ReadBytes(code_size));
			int position = buffer.position;
			buffer.position -= code_size;
			while (buffer.position < position)
			{
				byte b = buffer.ReadByte();
				bool flag = b != 254;
				OpCode opCode;
				if (flag)
				{
					opCode = OpCodes.OneByteOpCode[(int)b];
				}
				else
				{
					byte b2 = buffer.ReadByte();
					opCode = OpCodes.TwoBytesOpCode[(int)b2];
				}
				switch (opCode.OperandType)
				{
				case OperandType.InlineBrTarget:
				case OperandType.InlineI:
				case OperandType.ShortInlineR:
					buffer.position += 4;
					break;
				case OperandType.InlineField:
				case OperandType.InlineMethod:
				case OperandType.InlineTok:
				case OperandType.InlineType:
				{
					IMetadataTokenProvider provider = this.reader.LookupToken(new MetadataToken(buffer.ReadUInt32()));
					buffer.position -= 4;
					buffer.WriteUInt32(metadata.LookupToken(provider).ToUInt32());
					break;
				}
				case OperandType.InlineI8:
				case OperandType.InlineR:
					buffer.position += 8;
					break;
				case OperandType.InlineSig:
				{
					CallSite callSite = this.GetCallSite(new MetadataToken(buffer.ReadUInt32()));
					buffer.position -= 4;
					buffer.WriteUInt32(writer.GetStandAloneSignature(callSite).ToUInt32());
					break;
				}
				case OperandType.InlineString:
				{
					string @string = this.GetString(new MetadataToken(buffer.ReadUInt32()));
					buffer.position -= 4;
					buffer.WriteUInt32(new MetadataToken(TokenType.String, metadata.user_string_heap.GetStringIndex(@string)).ToUInt32());
					break;
				}
				case OperandType.InlineSwitch:
				{
					int num = buffer.ReadInt32();
					buffer.position += num * 4;
					break;
				}
				case OperandType.InlineVar:
				case OperandType.InlineArg:
					buffer.position += 2;
					break;
				case OperandType.ShortInlineBrTarget:
				case OperandType.ShortInlineI:
				case OperandType.ShortInlineVar:
				case OperandType.ShortInlineArg:
					buffer.position++;
					break;
				}
			}
		}

		// Token: 0x06000A86 RID: 2694 RVA: 0x0002FC08 File Offset: 0x0002DE08
		private void PatchRawSection(ByteBuffer buffer, MetadataBuilder metadata)
		{
			int position = base.Position;
			base.Align(4);
			buffer.WriteBytes(base.Position - position);
			byte b = this.ReadByte();
			bool flag = (b & 64) == 0;
			if (flag)
			{
				buffer.WriteByte(b);
				this.PatchRawSmallSection(buffer, metadata);
			}
			else
			{
				this.PatchRawFatSection(buffer, metadata);
			}
			bool flag2 = (b & 128) > 0;
			if (flag2)
			{
				this.PatchRawSection(buffer, metadata);
			}
		}

		// Token: 0x06000A87 RID: 2695 RVA: 0x0002FC7C File Offset: 0x0002DE7C
		private void PatchRawSmallSection(ByteBuffer buffer, MetadataBuilder metadata)
		{
			byte b = this.ReadByte();
			buffer.WriteByte(b);
			base.Advance(2);
			buffer.WriteUInt16(0);
			int count = (int)(b / 12);
			this.PatchRawExceptionHandlers(buffer, metadata, count, false);
		}

		// Token: 0x06000A88 RID: 2696 RVA: 0x0002FCBC File Offset: 0x0002DEBC
		private void PatchRawFatSection(ByteBuffer buffer, MetadataBuilder metadata)
		{
			base.Advance(-1);
			int num = this.ReadInt32();
			buffer.WriteInt32(num);
			int count = (num >> 8) / 24;
			this.PatchRawExceptionHandlers(buffer, metadata, count, true);
		}

		// Token: 0x06000A89 RID: 2697 RVA: 0x0002FCF4 File Offset: 0x0002DEF4
		private void PatchRawExceptionHandlers(ByteBuffer buffer, MetadataBuilder metadata, int count, bool fat_entry)
		{
			for (int i = 0; i < count; i++)
			{
				ExceptionHandlerType exceptionHandlerType;
				if (fat_entry)
				{
					uint num = this.ReadUInt32();
					exceptionHandlerType = (ExceptionHandlerType)(num & 7U);
					buffer.WriteUInt32(num);
				}
				else
				{
					ushort num2 = this.ReadUInt16();
					exceptionHandlerType = (ExceptionHandlerType)(num2 & 7);
					buffer.WriteUInt16(num2);
				}
				buffer.WriteBytes(this.ReadBytes(fat_entry ? 16 : 6));
				ExceptionHandlerType exceptionHandlerType2 = exceptionHandlerType;
				ExceptionHandlerType exceptionHandlerType3 = exceptionHandlerType2;
				if (exceptionHandlerType3 != ExceptionHandlerType.Catch)
				{
					buffer.WriteUInt32(this.ReadUInt32());
				}
				else
				{
					IMetadataTokenProvider provider = this.reader.LookupToken(this.ReadToken());
					buffer.WriteUInt32(metadata.LookupToken(provider).ToUInt32());
				}
			}
		}

		// Token: 0x04000597 RID: 1431
		internal readonly MetadataReader reader;

		// Token: 0x04000598 RID: 1432
		private int start;

		// Token: 0x04000599 RID: 1433
		private MethodDefinition method;

		// Token: 0x0400059A RID: 1434
		private MethodBody body;
	}
}
